package org.adw.library.widgets.discreteseekbar.internal;

import ohos.agp.animation.Animator;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.components.AttrSet;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.render.Canvas;
import ohos.agp.utils.Color;
import ohos.agp.window.dialog.PopupDialog;
import ohos.app.Context;
import org.adw.library.widgets.discreteseekbar.DiscreteSeekBar;
import org.adw.library.widgets.discreteseekbar.internal.drawable.MarkerDrawable;

public class PopupIndicator {
    private static final int ANIMATION_DURATION = 500;
    private MarkerDrawable markerDrawable;
    private PopupDialog popupDialog;
    private Component component;
    private int offsetY;
    private float radius;
    private int thumbSize;
    private AnimatorValue animatorValue = new AnimatorValue();
    private Context context;
    private float fraction;
    private float x;
    private float y;
    private String text;
    private boolean isOpen = false;
    private DiscreteSeekBar discreteSeekBar;
    private int padding;

    public PopupIndicator(DiscreteSeekBar discreteSeekBar, AttrSet attrSet, float markerLength, int thumbSize, int separation) {
        this.discreteSeekBar = discreteSeekBar;
        this.context = discreteSeekBar.getContext();
        this.thumbSize = thumbSize;
        offsetY = -thumbSize - separation;
        padding = AttrUtils.getDimensionFromAttr(attrSet, "dsb_indicator_textPadding", dp2px(6, context));
        radius = Math.max(markerLength / 2 + padding, dp2px(16,context));
        markerDrawable = new MarkerDrawable(context, attrSet);
    }

    public void refresh(float x, float y, String text) {
        this.x = x;
        this.y = y;
        this.text = text;
        if (component != null && isOpen) {
            component.invalidate();
        }
    }

    public boolean isOpen() {
        return isOpen;
    }

    public void setMarkLength(float markerLength) {
        radius = markerLength / 2 + padding;
        if (isOpen && component != null) {
            component.invalidate();
        }
    }

    public void setColors(int indicatorColor, int indicatorPressedColor) {
        markerDrawable.setColors(indicatorColor, indicatorPressedColor);
        if (isOpen && component != null) {
            component.invalidate();
        }
    }

    private void refreshDialog() {
        if (fraction >= 0.5f) {
            if (!isOpen) {
                component = new Component(context);
                component.setLayoutConfig(new ComponentContainer.LayoutConfig(ComponentContainer.LayoutConfig.MATCH_PARENT, ComponentContainer.LayoutConfig.MATCH_PARENT));
                component.addDrawTask(new Component.DrawTask() {
                    @Override
                    public void onDraw(Component component, Canvas canvas) {
                        markerDrawable.doDraw(canvas, x, y, offsetY,
                                DiscreteSeekBar.TOP_BAR_HEIGHT, text, (fraction - 0.5f) * 2, radius, thumbSize);
                    }
                });
                popupDialog = new PopupDialog(context, component,
                        context.getResourceManager().getDeviceCapability().screenDensity / 160 * context.getResourceManager().getDeviceCapability().width,
                        context.getResourceManager().getDeviceCapability().screenDensity / 160 * context.getResourceManager().getDeviceCapability().height
                );
                popupDialog.setCustomComponent(component);
                popupDialog.setTransparent(true);
                popupDialog.setBackColor(new Color(0x00000000));
                popupDialog.show();
                isOpen = true;
            }
        } else {
            if (isOpen) {
                isOpen = false;
                discreteSeekBar.invalidate();
                popupDialog.hide();
            }
        }
    }

    public void animateToPressed() {
        if (animatorValue != null && animatorValue.isRunning()) {
            animatorValue.stop();
        }
        animatorValue.setCurveType(Animator.CurveType.LINEAR);
        animatorValue.setDuration((long) (ANIMATION_DURATION - fraction * ANIMATION_DURATION));
        float start = fraction;
        float end = 1;
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                fraction = start + (end - start) * v;
                refreshDialog();
                context.getUITaskDispatcher().asyncDispatch(() -> {
                    if (component != null) {
                        component.invalidate();
                    }
                });
            }
        });
        animatorValue.start();
    }

    public void animateToNormal() {
        if (animatorValue != null && animatorValue.isRunning()) {
            animatorValue.stop();
        }
        animatorValue.setDuration((long) (fraction * ANIMATION_DURATION));
        float start = fraction;
        float end = 0;
        animatorValue.setValueUpdateListener(new AnimatorValue.ValueUpdateListener() {
            @Override
            public void onUpdate(AnimatorValue animatorValue, float v) {
                fraction = start + (end - start) * v;
                refreshDialog();
                context.getUITaskDispatcher().asyncDispatch(new Runnable() {
                    @Override
                    public void run() {
                        if (component != null) {
                            component.invalidate();
                        }
                    }
                });
            }
        });
        animatorValue.start();
    }

    private int dp2px(float dp, Context context) {
        return (int) (context.getResourceManager().getDeviceCapability().screenDensity / 160 * dp);
    }
}
